/*
- Copyright (C) 2003 Robert Lipe, robertlipe@usa.net
+ Copyright (C) 2003-2013 Robert Lipe, robertlipe@gpsbabel.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
#include "defs.h"
#include "cet_util.h"
-#if HAVE_LIBEXPAT
-#include <expat.h>
-static XML_Parser psr;
-#endif
-
-static waypoint* wpt_tmp;
-
-static gbfile* fin, *fout;
+#include <QtCore/QXmlStreamReader>
+#include "src/core/file.h"
static char* noretired = NULL;
+static const char* read_fname = NULL;
static
arglist_t nav_args[] = {
};
#define MYNAME "navicache"
-#define MY_CBUF 4096
#define NC_URL "http://www.navicache.com/cgi-bin/db/displaycache2.pl?CacheID="
-#if ! HAVE_LIBEXPAT
-static void
-nav_rd_init(const char* fname)
-{
- fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n");
-}
-
-static void
-nav_read(void)
-{
-}
-#else
-
static struct
nc_type_mapping {
geocache_type type;
static
geocache_type
-nc_mktype(const char* t)
+nc_mktype(const QString& t)
{
int i;
int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]);
for (i = 0; i < sz; i++) {
- if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) {
+ if (0 == t.compare(nc_type_map[i].name, Qt::CaseInsensitive)) {
return nc_type_map[i].type;
}
}
static
geocache_container
-nc_mkcont(const char* t)
+nc_mkcont(const QString& t)
{
int i;
int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]);
for (i = 0; i < sz; i++) {
- if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) {
+ if (0 == t.compare(nc_container_map[i].name, Qt::CaseInsensitive)) {
return nc_container_map[i].type;
}
}
}
static void
-nav_start(void* data, const XML_Char* xml_el, const XML_Char** xml_attr)
+nav_rd_init(const char* fname)
{
- const char* el;
- const char** attr;
-
- el = xml_convert_to_char_string(xml_el);
- attr = xml_convert_attrs_to_char_string(xml_attr);
- if (0 == strcmp(el, "CacheDetails")) {
- const char** ap;
- geocache_data* gc_data;
- wpt_tmp = waypt_new();
- gc_data = waypt_alloc_gc_data(wpt_tmp);
-
- for (ap = attr; *ap; ap+=2) {
- if (0 == strcmp(ap[0], "cache_id")) {
- int id;
-
- id = atoi(ap[1]);
- xasprintf(&wpt_tmp->shortname, "N%05X", id);
- UrlLink l(QString(NC_URL) + QString::number(id));
- wpt_tmp->AddUrlLink(l);
- } else if (0 == strcmp(ap[0], "name")) {
- wpt_tmp->description = xstrdup(ap[1]);
- } else if (0 == strcmp(ap[0], "user_name")) {
- gc_data->placer = ap[1];
- } else if (0 == strcmp(ap[0], "latitude")) {
- sscanf(ap[1], "%lf",
- &wpt_tmp->latitude);
- } else if (0 == strcmp(ap[0], "longitude")) {
- sscanf(ap[1], "%lf",
- &wpt_tmp->longitude);
- } else if (0 == strcmp(ap[0], "longitude")) {
- sscanf(ap[1], "%lf",
- &wpt_tmp->longitude);
- } else if (0 == strcmp(ap[0], "difficulty")) {
- float x;
- sscanf(ap[1], "%f", &x);
- gc_data->diff = x * 10;
- } else if (0 == strcmp(ap[0], "terrain")) {
- float x;
- sscanf(ap[1], "%f", &x);
- gc_data->terr = x * 10;
- } else if (0 == strcmp(ap[0], "cache_type")) {
- gc_data->type = nc_mktype(ap[1]);
- if (!strcmp(ap[1], "normal")) {
- wpt_tmp->icon_descr = "Geocache-regular";
- } else if (!strcmp(ap[1], "multi-part")) {
- wpt_tmp->icon_descr = "Geocache-multi";
- } else if (!strcmp(ap[1], "moving_travelling")) {
- wpt_tmp->icon_descr = "Geocache-moving";
- } else {
- // WARNING: casting away const-ness.
- xasprintf((char**)&wpt_tmp->icon_descr,
- "Geocache-%-.20s", ap[1]);
- }
- } else if (0 == strcmp(ap[0], "hidden_date")) {
- struct tm tm;
-
- sscanf(ap[1], "%d-%d-%d",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday);
- tm.tm_mon -= 1;
- tm.tm_year -= 1900;
- tm.tm_isdst = 0;
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- wpt_tmp->SetCreationTime(mktime(&tm));
- } else if (0 == strcmp(ap[0], "retired")) {
- if (!strcmp(ap[1], "yes") && noretired) {
- xfree(wpt_tmp);
- return;
- }
- } else if (0 == strcmp(ap[0], "cache_size")) {
- gc_data->container = nc_mkcont(ap[1]);
- } else if (0 == strcmp(ap[0], "description")) {
- gc_data->desc_long.is_html = 1;
- gc_data->desc_long.utfstring = ap[1];
- } else if (0 == strcmp(ap[0], "comments")) {
- gc_data->desc_short.is_html = 1;
- gc_data->desc_short.utfstring = ap[1];
- }
+ read_fname = fname;
+}
+
+static void
+NaviReadCache(const QXmlStreamReader& reader) {
+ const QXmlStreamAttributes a = reader.attributes();
+ waypoint* wpt_tmp = waypt_new();
+ geocache_data* gc_data;
+ gc_data = waypt_alloc_gc_data(wpt_tmp);
+ if (a.hasAttribute("cache_id")) {
+ int n = a.value("cache_id").toString().toInt();
+ QString fn = QString("N%1").arg(n, 5, 16, QChar('0'));
+ wpt_tmp->shortname = xstrdup(CSTR(fn));
+
+ UrlLink l(QString(NC_URL) + QString::number(n));
+ wpt_tmp->AddUrlLink(l);
+ }
+ if (a.hasAttribute("name")) {
+ wpt_tmp->description = xstrdup(CSTR(a.value("name").toString()));
+ }
+ if (a.hasAttribute("user_name")) {
+ gc_data->placer = a.value("user_name").toString();
+ }
+
+ if (a.hasAttribute("latitude")) {
+ wpt_tmp->latitude = a.value("latitude").toString().toDouble();
+ }
+ if (a.hasAttribute("longitude")) {
+ wpt_tmp->longitude = a.value("longitude").toString().toDouble();
+ }
+
+ if (a.hasAttribute("difficulty")) {
+ gc_data->diff = a.value("difficulty").toString().toDouble() * 10;
+ }
+ if (a.hasAttribute("terrain")) {
+ gc_data->terr = a.value("terrain").toString().toDouble() * 10;
+ }
+
+ if (a.hasAttribute("cache_type")) {
+ QString t = a.value("cache_type").toString();
+ gc_data->type = nc_mktype(t);
+ if (t == "normal") {
+ wpt_tmp->icon_descr = "Geocache-regular";
+ } else if (t == "multi-part") {
+ wpt_tmp->icon_descr = "Geocache-multi";
+ } else if (t == "moving_travelling") {
+ wpt_tmp->icon_descr = "Geocache-moving";
+ } else {
+ wpt_tmp->icon_descr = QString("Geocache-%-%1").arg(t);
}
- waypt_add(wpt_tmp);
}
- xml_free_converted_attrs(attr);
- xml_free_converted_string(el);
-}
+ if (a.hasAttribute("hidden_date")) {
+ QString h = a.value("hidden_date").toString();
+ QDateTime hd = QDateTime::fromString(h, "yyyy-MM-dd");
+ wpt_tmp->SetCreationTime(hd);
+ }
-static void
-nav_end(void* data, const XML_Char* el)
-{
-}
+ if (a.hasAttribute("retired")) {
+ if (a.value("terrain").toString() == "yes" && noretired) {
+ waypt_free(wpt_tmp);
+ return;
+ }
+ }
-static void
-nav_rd_init(const char* fname)
-{
- fin = gbfopen(fname, "r", MYNAME);
+ if (a.hasAttribute("cache_size")) {
+ gc_data->container = nc_mkcont(a.value("cache_size").toString());
+ }
- psr = XML_ParserCreate(NULL);
- if (!psr) {
- fatal(MYNAME ":Cannot create XML parser\n");
+ if (a.hasAttribute("description")) {
+ gc_data->desc_long.is_html = true;
+ gc_data->desc_long.utfstring = a.value("description").toString();
}
- XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL);
- XML_SetElementHandler(psr, nav_start, nav_end);
+ if (a.hasAttribute("comments")) {
+ gc_data->desc_short.is_html = true;
+ gc_data->desc_short.utfstring = a.value("comments").toString();
+ }
+
+
+ waypt_add(wpt_tmp);
}
static void
nav_read(void)
{
- int len;
- char buf[MY_CBUF];
-
- while ((len = gbfread(buf, 1, sizeof(buf), fin))) {
- if (!XML_Parse(psr, buf, len, gbfeof(fin))) {
- fatal(MYNAME ":Parse error at %d: %s\n",
- (int) XML_GetCurrentLineNumber(psr),
- XML_ErrorString(XML_GetErrorCode(psr)));
+ QXmlStreamReader reader;
+ gpsbabel::File file(read_fname);
+ file.open(QIODevice::ReadOnly);
+ reader.setDevice(&file);
+
+ while (!reader.atEnd()) {
+ if (reader.name() == "CacheDetails" &&
+ reader.tokenType() == QXmlStreamReader::StartElement) {
+ NaviReadCache(reader);
}
+ reader.readNextStartElement();
}
-
- XML_ParserFree(psr);
}
-#endif
-
static void
nav_rd_deinit(void)
{
- gbfclose(fin);
}
static void
nav_wr_init(const char* fname)
{
fatal(MYNAME ": Does not support writing Navicache files.\n");
- fout = gbfopen(fname, "w", MYNAME);
}
static void
nav_wr_deinit(void)
{
- gbfclose(fout);
}
static void